<template>
  <div id="detail">
    <detail-nav-bar @titleClick="titleClick" class="detail-nav" ref="nav"></detail-nav-bar>

    <scroll class="content" ref="scroll" @scroll="contentScroll" :probe-type="3">
      <detail-swiper :top-images="topImages"></detail-swiper>
      <detail-base-info :goods="goods"></detail-base-info>
      <detail-shop-info :shop="shop"></detail-shop-info>
      <detail-goods-info :detail-info="detailInfo" @detailImageLoad="detailImageLoad"></detail-goods-info>
      <detail-param-info ref="params" :param-info="paramInfo"></detail-param-info>
      <detail-comment-info ref="comment" :comment-info="commentInfo"></detail-comment-info>
      <good-list ref="recommend" :goods="recommends"></good-list>
    </scroll>

    <detail-bottom-bar @addToCart="addToCart"></detail-bottom-bar>

    <back-top @click.native="backClick" v-show="isShowBackTop"></back-top>

<!--    <toast :message="message" :show="show"></toast>-->
  </div>
</template>

<script>
import Scroll from "components/common/scroll/Scroll";
import GoodList from "components/content/goods/GoodsList";

import DetailNavBar from "./childComps/DetailNavBar";
import DetailSwiper from "./childComps/DetailSwiper";
import DetailBaseInfo from "./childComps/DetailBaseInfo";
import DetailShopInfo from "./childComps/DetailShopInfo";
import DetailGoodsInfo from "./childComps/DetailGoodsInfo";
import DetailParamInfo from "./childComps/DetailParamInfo";
import DetailCommentInfo from "./childComps/DetailCommentInfo";
import DetailBottomBar from "./childComps/DetailBottomBar";

import {getCommentInfo,getRecommend,getDetail,Goods,Shop,GoodsParam} from "network/detail";

import {debounce} from "common/utils";

import {itemListenerMixin,backTopMixin} from "common/mixin";

// 将Actions中的方法映射到...mapmapActions['函数名']，直接this.函数名就可以调用Actions中的方法，
// 而不需要采用this.$store.dispatch('addCart',product)的方式调用
import {mapActions} from 'vuex'
import Toast from "../../components/common/toast/Toast";


export default {
  name: "Detail",
  components: {
    // Toast,
    DetailBottomBar,
    GoodList,
    DetailCommentInfo,
    DetailParamInfo, DetailGoodsInfo, Scroll, DetailShopInfo, DetailBaseInfo, DetailSwiper, DetailNavBar},
  data () {
    return {
        id: null,
        topImages: [],
        goods: {},
        shop: {},
        detailInfo: {},
        paramInfo: {},
        commentInfo: {},
        recommends:[],
      // 主题的y值,获取每个主题的offstop然后放进去
        themeTopYs:[],
      // 获取主题y值的函数
        getThemTopY: null,
      // 用于记录滚动位置
        currentIndex: 0,
        // message:'',
        // show:false
    }
  },
  mixins:[itemListenerMixin,backTopMixin],

  created() {
    // 1.获取路由中的id
    this.id = this.$route.params.id

    // 2.根据id请求详情数据
    getDetail(this.id).then(res => {
      const data = res.data
      // 2.1获取顶部的图片轮播数据
      this.topImages = [data.detailPicture,data.picture]
      // console.log(this.topImages)

      // 2.2获取商品信息数据,在将res传递给Goods类方法，提取其中的值封装成为一个新的对象
        this.goods = new Goods(data)

      // 2.3店铺信息对象
      this.shop = new Shop(data)

      // 2.4商品详情数据
      this.detailInfo = data.detailInfo = {
        desc : '新款上市',
        detailImage:[
          {
            anchor: "model_img",
            key:'穿着效果',
            list:['http://file.gzedu.com/upload/downloadFile.do?uploadInfoId=bc264bfb80e14a28a560a35ceeff76ca',
              'http://file.gzedu.com/upload/downloadFile.do?uploadInfoId=7da4dfe096124cb6824fcb29c138128b',
              'http://file.gzedu.com/upload/downloadFile.do?uploadInfoId=3291d7878c784b8fa1c811078fe55004']
          }
        ]
      }

      // 2.5商品参数数据
      this.paramInfo = new GoodsParam()
    })

    // 2.6请求评论数据：
    getCommentInfo(this.id).then(res => {
      const data = res.data
      if(data.length !==0){
        this.commentInfo= data[0]
      }
    })

    // 3.请求推荐数据
    getRecommend().then(res => {
      this.recommends = res.data
    })

    // 4.给getThemeTopY赋值,采用防抖函数，在detailImageLoad加载完之后进行调用
    this.getThemTopY = debounce(() => {
      this.themeTopYs.push(0);
      this.themeTopYs.push(this.$refs.params.$el.offsetTop-5);
      this.themeTopYs.push(this.$refs.comment.$el.offsetTop-5);
      this.themeTopYs.push(this.$refs.recommend.$el.offsetTop-5);
      this.themeTopYs.push(Number.MAX_VALUE)
    },100)
  },
  methods: {
    ...mapActions(['addCart']),
    // 监听详情图片加载
    detailImageLoad() {
      this.newRefresh()
      // 在图片加载完成，调用getThemeTopY函数给themeTopYs赋值，然后在titleClick就可以根据获得的值，在点击按钮时进行对应的跳转
      this.getThemTopY()
    },
    // 监听主题tab点击,要在scroll组件设置@scroll="contentScroll" :probe-type="3"
    titleClick(index) {
      this.$refs.scroll.scrollTo1(0,-this.themeTopYs[index],100)
    },
    // 监听滚动位置
    contentScroll(position) {
      // 1.获取y值
      const positionY= -position.y
      // 2.positionY和主题的themeTopYs中的值进行对比
      let length = this.themeTopYs.length
      // [0,7999,9120,9452,num.max_value]
//       for循环
//       1、for有三个表达式：①声明循环变量；②判断循环条件；③更新循环变量；
// 　　　　三个表达式之间，用;分割，for循环三个表达式都可以省略，但是两个“;”缺一不可。
// 　　    2、for循环的执行特点：先判断再执行，与while相同
//         3、for循环三个表达式都可以有多部分组成，第二部分多个判断条件用&& ||连接，第一三部分用逗号分割；
      for (let i = 0;i < length-1;i++) {
        // 如果this.currentIndex不等于i,则返回i
        // 条件1判断当前处于的位置，当前主题位置与i相同，不执行后面的代码
        // 条件2判断当前y值是否>=以i为下标的themeTopYs中的值，再判断当前位置是否小于themeTopYs中以i+1为下标的值
        // 条件都满足，将i赋值给currentIndex进行保存，再将currentIndex赋值给nav.currentIndex用于改变主题标签活跃展示
        if (this.currentIndex !== i && (positionY >= this.themeTopYs[i] && positionY < this.themeTopYs[i+1])) {
          this.currentIndex = i;
          this.$refs.nav.currentIndex = this.currentIndex
        }
      }

      // 3.是否显示返回顶部
      this.listenShowBackTop(position)
    },

    // 监听点击添加购物车，子组件点击，传递事件给父组件
    addToCart() {
      // 1.获取购物车需展示的数据信息
      const product = {}
      product.image = this.topImages[0]
      product.title = this.goods.title
      product.desc = this.goods.desco
      product.price = this.goods.newPrice
      product.id = this.id


      // 2.将商品添加到购物车
      // 采用vuex,因为事件总线的话传递时，如果组件没有创建出来，就不会进行监听，需要先将数据放在一个公共的地方，再进行组件创建展示
      // this.$store.commit('addCart',product)
      // 注意；如果想要让组件知道vuex中做了什么操作，要运用promise
      // 调用addCart方式1
      // this.$store.dispatch('addCart',product).then(res => {
      //   console.log(res)
      // })
      // 调用addCart方式2
      if (product.image) {
        this.addCart(product).then(res => {
          //   this.show = true;
          //   this.message = res;
          //   setTimeout(() => {
          //       this.show = false,
          //       this.message = ''
          //   },1500)
          //   console.log(this.$toast)
          this.$toast.show(res,2000)
        })
      }
    }
  },
  mounted() {
    // 防抖内容整合到了混入中了
  },
  // 被keep-alive排除的组件不能采用activated、deactivated两个涉及缓存的函数，离开时会调用destroyed
  destroyed() {
    this.$bus.$off('itemImageLoad',this.itemImgListener)
  }
}
</script>

<style scoped>
  #detail {
    /*注意：相对定位不会改变元素位置，不要随便使用绝对定位*/
    /*设置detail覆盖掉底部导航栏*/
    position: relative;
    /*此处可以优先于底部导航栏显示*/
    z-index: 10;
    /*背景用于覆盖底部导航栏*/
    background-color: #fff;
    /*用于撑开展示当前内容*/
    height: 100vh;
  }
    /*顶部导航栏显示设置*/
  .detail-nav {
    position: relative;
    z-index: 9;
    background-color: #fff;
  }

  /*给srocll组件大壳子设置可滚动高度，父元素也要设置高度，否则还是无法滚动*/
  .content {
    overflow: hidden;
    /*绝对定位,要在上层盒子配置相对定位*/
    position: absolute;
    /*距离顶*/
    top: 50px;
    /*距离底部*/
    bottom: 50px;
    left: 0;
    right: 0;
  }


</style>
